﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace CBS.Common
{
    /// <summary>
    /// 
    /// </summary>
    public class PropertyHelper
    {
        /// <summary>  
        /// 反射得到实体类的字段名称和值  
        /// var dict = GetProperties(model);  
        /// </summary>  
        /// <typeparam name="T">实体类</typeparam>  
        /// <param name="t">实例化</param>  
        /// <returns></returns>  
        public static Dictionary<object, object> GetProperties<T>(T t)
        {
            var ret = new Dictionary<object, object>();
            if (t == null) { return null; }
            PropertyInfo[] properties = t.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public);
            if (properties.Length <= 0) { return null; }
            foreach (PropertyInfo item in properties)
            {
                string name = item.Name;
                object value = item.GetValue(t, null);
                if (item.PropertyType == typeof(DateTime))
                {
                    ret.Add(name, Convert.ToDateTime(value).ToString("yyyy/MM/dd HH:mm:ss"));
                }
                else if (item.PropertyType.IsValueType || item.PropertyType.Name.StartsWith("String"))
                {
                    ret.Add(name, value);
                }
            }
            return ret;
        }

        /// <summary>
        /// 给对象赋值的方法(不赋地址)(同一个类型)
        /// </summary>
        /// <param name="left">=号左边</param>
        /// <param name="right">=号右边</param>


        /// <summary>
        /// 给对象赋值的方法(不赋地址)(不同类型)
        /// </summary>
        /// <param name="left">=号左边</param>
        /// <param name="right">=号右边</param>
        public static TOut Assignment<TOut, TIn>(TIn right) where TOut : new()
        {
            if (right == null)
            {
                return default(TOut);
            }

            TOut left = new TOut();
            var ltype = left.GetType();
            List<PropertyInfo> lList = typeof(TOut).GetProperties().ToList();
            List<PropertyInfo> rList = typeof(TIn).GetProperties().ToList();
            for (int i = 0; i < rList.Count; i++)
            {
                //根据属性名获得指定的属性对象
                PropertyInfo gc = ltype.GetProperty(rList[i].Name);
                //验证属性是否可以Set
                if (gc != null && gc.CanWrite == true)
                {
                    try
                    {

                        var value = rList.Where(t => t.Name == gc.Name).FirstOrDefault().GetValue(right, null);
                        //TODO 
                        if (gc.PropertyType.FullName.Contains("String") && value == null) { value = ""; }
                        //设置属性的值
                        gc.SetValue(left, value, null);
                    }
                    catch
                    {
                    }
                }
            }
            return left;
        }

        /// <summary>
        /// 将一组List赋值到另一组List(不同类型)
        /// </summary>
        /// <param name="lift"></param>
        /// <param name="right"></param>
        public static List<TOut> Assignment<TOut, TIn>(List<TIn> right) where TOut : new()
        {
            List<TOut> left = new List<TOut>();
            foreach (var r in right)
            {
                left.Add(Assignment<TOut, TIn>(r));
            }
            return left;
        }


        public static TOut OverLoadObject<TOut, TIn>(TIn objIn, TOut objOut, List<string> objKey = null, List<string> objOverLoadField = null)
        {
            if (objIn == null || objOut == null)
            {
                return default(TOut);
            }

            List<PropertyInfo> lList = typeof(TOut).GetProperties().ToList();
            List<PropertyInfo> rList = typeof(TIn).GetProperties().ToList();
            for (int i = 0; i < lList.Count; i++)
            {
                if (rList[i].Name == "id")
                {
                    continue;
                }

                if (objKey != null && objKey.Count > 0 && objKey.Any(t => t == rList[i].Name))
                {
                    continue;
                }

                //根据属性名获得指定的属性对象
                PropertyInfo gc = typeof(TIn).GetProperty(rList[i].Name);

                //验证属性是否可以Set
                if (gc != null && gc.CanWrite == true)
                {
                    try
                    {
                        var value = rList.FirstOrDefault(t => t.Name == gc.Name).GetValue(objIn, null);
                        if (value == null)
                        {
                            continue;
                        }
                        //TODO 
                        if (gc.PropertyType.FullName.Contains("String") && value == null) { value = ""; }
                        //设置属性的值
                        gc.SetValue(objOut, value, null);
                    }
                    catch
                    {
                    }
                }

            }
            return objOut;
        }
    }
}

